package com.extendRelation.service;

import com.extendRelation.model.Company;
import com.extendRelation.model.Employee;
import com.extendRelation.model.HourlyEmployee;
import com.extendRelation.model.SalariedEmployee;
import com.utils.HibernateUtil;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class BusinessService {

    private SessionFactory sessionFactory = new HibernateUtil().getSessionFactory();

    private void saveEmployee(Employee employee) {
        Session session = sessionFactory.openSession();
        Transaction tx = null;
        try {
            tx = session.beginTransaction();
            session.save(employee);
            tx.commit();
        } catch (RuntimeException e) {
            if (tx != null) {
                tx.rollback();
            }
            System.out.println("");
            throw e;
        } finally {
            session.close();
        }
    }

    private List findAllEmployees() {
        Session session = sessionFactory.openSession();
        Transaction tx = null;

        try {
            List<Object> results = new ArrayList<>();
            tx = session.beginTransaction();
            List hourlyEmployees = session.createQuery("from HourlyEmployee").list();
            results.addAll(hourlyEmployees);

            List salariedEmployees = session.createQuery("from SalariedEmployee").list();
            results.addAll(salariedEmployees);

            tx.commit();
            return results;
        } catch (RuntimeException e) {
            if (tx != null) {
                tx.rollback();
            }
            throw e;
        } finally {
            session.close();
        }
    }

    private Company loadCompany(long id) {
        Session session = sessionFactory.openSession();
        Transaction tx = null;
        try {
            tx = session.beginTransaction();
            Company company = (Company) session.get(Company.class, id);

            List hourlyEmployees = session
                    .createQuery("from HourlyEmployee h where h.company.id=" + id)
                    .list();
            company.getEmployees().addAll(hourlyEmployees);

            List salariedEmployees = session
                    .createQuery("from SalariedEmployee s where s.company.id=" + id)
                    .list();
            company.getEmployees().addAll(salariedEmployees);

            tx.commit();
            return company;
        } catch (RuntimeException e) {
            if (tx != null) {
                tx.rollback();
            }
            throw e;
        } finally {
            session.close();
        }
    }

    private void printAllEmployees(Iterator it) {
        while (it.hasNext()) {
            Employee e = (Employee) it.next();
            if (e instanceof HourlyEmployee) {
                System.out.println("HourlyEmployee Rate : " + ((HourlyEmployee) e).getRate());
            } else
                System.out.println("SalariedEmployee Salary : " + ((SalariedEmployee) e).getSalary());
        }
    }

    private void test() {
        List employees = findAllEmployees();
        printAllEmployees(employees.iterator());

        Company company = loadCompany(1);
        printAllEmployees(company.getEmployees().iterator());

        Employee employee = new HourlyEmployee("Mary", 300, company);
        saveEmployee(employee);

        sessionFactory.close();
    }
    public static void main(String args[]) {
        new BusinessService().test();
    }
}
